package com.novunda.platform.common.dialects.shiro.processor;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.thymeleaf.IEngineConfiguration;
import org.thymeleaf.context.ITemplateContext;
import org.thymeleaf.engine.AttributeName;
import org.thymeleaf.exceptions.TemplateProcessingException;
import org.thymeleaf.model.IProcessableElementTag;
import org.thymeleaf.processor.element.AbstractAttributeTagProcessor;
import org.thymeleaf.processor.element.IElementTagStructureHandler;
import org.thymeleaf.standard.expression.IStandardExpression;
import org.thymeleaf.standard.expression.IStandardExpressionParser;
import org.thymeleaf.standard.expression.StandardExpressions;
import org.thymeleaf.templatemode.TemplateMode;

/**
 * @author linfeng
 * @since 2016/9/9
 */
public abstract class AbstractAttributeProcessor extends AbstractAttributeTagProcessor {

    private static final Logger log = LoggerFactory.getLogger(AbstractAttributeProcessor.class);

    protected AbstractAttributeProcessor(TemplateMode templateMode, String dialectPrefix, String elementName,
                                         boolean prefixElementName, String attributeName, boolean prefixAttributeName, int precedence,
                                         boolean removeAttribute) {
        super(templateMode, dialectPrefix, elementName, prefixElementName, attributeName, prefixAttributeName,
                precedence, removeAttribute);
    }

    @Override
    protected void doProcess(ITemplateContext context, IProcessableElementTag tag,
                             AttributeName attributeName, String attributeValue, IElementTagStructureHandler structureHandler) {

        if (StringUtils.isBlank(attributeValue)) {

            structureHandler.removeElement();

        } else {

            final IEngineConfiguration configuration = context.getConfiguration();

            String permission;
            try {
                /**
                 * 获得thymeleaf标准表达式解析器
                 */
                final IStandardExpressionParser parser = StandardExpressions.getExpressionParser(configuration);

                /**
                 * 解析属性值为thymeleaf的规范表达式
                 */
                final IStandardExpression expression = parser.parseExpression(context, attributeValue);

                /*
                 * 执行刚刚解析的表达式
                 */
                permission = (String) expression.execute(context);
            } catch (TemplateProcessingException e) {

                if (log.isWarnEnabled()) {
                    log.warn(e.getMessage());
                }
                permission = attributeValue;
            }

            if (StringUtils.isBlank(permission)) {
                structureHandler.removeElement();
            }

            doShiroHandler(context, tag, attributeName, permission, structureHandler);

        }

    }

    protected abstract void doShiroHandler(ITemplateContext context, IProcessableElementTag tag,
                                           AttributeName attributeName, String attributeValue, IElementTagStructureHandler structureHandler);


}
